package drds.global_transaction.dubbo;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;
import drds.global_transaction.api.global_transaction_id_context.GlobalTransactionIdContexts;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Activate(group = { Constants.PROVIDER, Constants.CONSUMER }, order = 100)
public class GlobalTransactionPropagationFilter implements Filter
{

	@Override
	public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException
	{
		// idInGlobalTransactionIdContext优先级大于idInRpcContext,
		// 当idInGlobalTransactionIdContext存在则需要覆盖idInRpcContext,
		// 当idInGlobalTransactionIdContext不存在,如果idInRpcContext不存在则需要绑定到idInGlobalTransactionIdContext
		//
		String idInGlobalTransactionIdContext = GlobalTransactionIdContexts.getGlobalTransactionIdWithAddressAndPort();
		String idInRpcContext = RpcContext.getContext().getAttachment(GlobalTransactionIdContexts.global_transaction_id_with_address_and_port_key);
		//
		boolean bind = false;
		if (idInGlobalTransactionIdContext != null)
		{
			RpcContext.getContext().setAttachment(GlobalTransactionIdContexts.global_transaction_id_with_address_and_port_key, idInGlobalTransactionIdContext);
		} else
		{
			if (idInRpcContext != null)
			{
				// 这里才是重点
				GlobalTransactionIdContexts.bind(idInRpcContext);
				bind = true;
			} else
			{
				// ...
			}
		}
		try
		{
			return invoker.invoke(invocation);

		} finally
		{
			if (bind)
			{
				// unbindId==idInRpcContext?
				String unbindId = GlobalTransactionIdContexts.unbind();
				if (!idInRpcContext.equalsIgnoreCase(unbindId))
				{
					if (unbindId != null)
					{
						GlobalTransactionIdContexts.bind(unbindId);
					}
				}
			}
		}
	}
}
